package no.eirikb.bomberman.server;

import java.util.Hashtable;
import no.eirikb.bomberman.shared.Game;
import no.eirikb.bomberman.applet.game.Pos;
import no.eirikb.bomberman.shared.User;

/**
 *
 * @author eirikb
 */
public class GameHandler {

    private Hashtable<String, Game> games;
    private final int SIZE = 32; // WTH!

    public GameHandler() {
        games = new Hashtable<String, Game>();
    }

    public boolean createGame(Game game, User user) {
        Game game2;
        if ((game2 = (games.put(game.getName(), game))) != null) {
            games.put(game.getName(), game2);
            return false;
        }
        game.addUser(user);
        user.setGameName(game.getName());
        return true;
    }

    public Game joinGame(String gameName, User user) {
        Game game;
        if ((game = games.get(gameName)) != null &&
                game.getUsers().size() < game.getMax()) {
            game.addUser(user);
            user.setGameName(gameName);
            return game;
        } else {
            return null;
        }
    }

    public Game leaveGame(User user) {
        Game game;
        if (user.getGameName() != null &&
                (game = games.get(user.getGameName())) != null) {
            game.removeUser(user);
            user.setGameName(null);
            if (game.getUsers().size() <= 0) {
                games.remove(game.getName());
                return game;
            } else {
                return game;
            }
        } else {
            return null;
        }
    }

    public Game setReady(User user, boolean ready) {
        Game game;
        if (user.getGameName() != null &&
                (game = games.get(user.getGameName())) != null) {
            user.setReady(ready);
            if (game.isReady()) {
                resetUsers(game);
            }
            return game;
        } else {
            return null;
        }
    }

    public Game[] getGameList() {
        return games.values().toArray(new Game[0]);
    }

    public Game getGame(String gameName) {
        return games.get(gameName);
    }

    /**
     * x-y-pos:
     * 0,0   1,0    2,2
     * 0,1          2,1
     * 0,2   1,2    2,2
     * 
     * by i:
     * 0     4      1
     * 5            6
     * 2     7      3
     */
    public void resetUsers(Game game) {
        int i = 0;
        for (User u : game.getUsers().values()) {
            int x = 0;
            int y = 0;
            switch (i) {
                case 1:
                    x = 2;
                    break;
                case 2:
                    y = 2;
                    break;
                case 3:
                    x = 2;
                    y = 2;
                    break;
                case 4:
                    x = 1;
                    break;
                case 5:
                    y = 1;
                    break;
                case 6:
                    x = 2;
                    y = 1;
                    break;
                case 7:
                    x = 1;
                    y = 2;
                    break;
            }
            int w = (game.getWidth() * SIZE) - SIZE;
            int h = (game.getHeight() * SIZE) - SIZE;
            x = x * (w / 2);
            y = y * (h / 2);
            int x1 = x / SIZE;
            int y1 = y / SIZE;
            for (int j = x1 - 1; j <= x1 + 1; j++) {
                for (int k = y1 - 1; k <= y1 + 1; k++) {
                    game.removeBrick(j, k);
                }
            }
            u.setPos(new Pos(x, y));
            u.setSpeed(game.getStartSpeed());
            u.setBombs(game.getStartBombs());
            u.setBombSize(game.getStartBombSize());
            u.setBombTime(game.getStartBombTime());
            i++;
        }
    }

    public Pos getUserPos(ServerUser su) {
        User u = su.getUser();
        if (!u.isWalking()) {
            return u.getLastPos();
        } else {
            int x = (int) u.getLastPos().getX();
            int y = (int) u.getLastPos().getY();
            long time = (System.currentTimeMillis() - su.getTime()) / 50;
            int distance = (int) (time * u.getSpeed());
            switch (u.getWay()) {
                case LEFT:
                    return new Pos(x -= distance, y);
                case UP:
                    return new Pos(x, y -= distance);
                case RIGHT:
                    return new Pos(x += distance, y);
                case DOWN:
                    return new Pos(x, y += distance);
            }
        }
        return null;
    }
}
